Imports System
Imports System.Collections.Generic
Imports Microsoft.Win32


Namespace C4F.DevKit.PreviewHandler.PreviewHandlerHost
	''' <summary>
	''' Class used to traverse the registry to read all the file previewer registrations that exist on the system
	''' The majority of this code and logic comes from the Preview Handler Association Editor that Stephen Toub wrote
	''' and posted about on his blog.  http://blogs.msdn.com/toub/archive/2006/12/14/preview-handler-association-editor.aspx
	''' We made a few minor tweaks for our purposes, but the core of the logic is his.  Thanks to Stephen for sharing this code.
	''' </summary>
	Friend Class PreviewHandlerRegistryAccessor
		Private Const BaseRegistryKey As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\PreviewHandlers"
		Private Const BaseClsIDKey As String = "HKEY_CLASSES_ROOT\{0}\shellex\{{8895b1c6-b41f-4c1c-a562-0d564250836f}}"
		Private Const BaseClsIdKey2 As String = "HKEY_CLASSES_ROOT\SystemFileAssociations\{0}\shellex\{{8895b1c6-b41f-4c1c-a562-0d564250836f}}"


		''' <summary>
		''' Read the registry to learn about the preview handlers that are available on this machine
		''' Return a structure containing 2 collections.  One of all the file extensions and whether we found a preview handler
		''' registered, and one of the preview handlers and their CLSIDs
		''' </summary>
		Friend Shared Function LoadRegistrationInformation() As RegistrationData
			' Load and sort all preview handler information from registry
			Dim handlers As List(Of PreviewHandlerInfo) = New List(Of PreviewHandlerInfo)()
			Using handlersKey As RegistryKey = Registry.LocalMachine.OpenSubKey(BaseRegistryKey)
				For Each id As String In handlersKey.GetValueNames()
					Dim handler As PreviewHandlerInfo = New PreviewHandlerInfo()
					handler.ID = id
					handler.Name = TryCast(handlersKey.GetValue(id, Nothing), String)
					handlers.Add(handler)
				Next id
			End Using
			handlers.Sort(AddressOf AnonymousMethod1)

			' Create a lookup table of preview handler ID -> PreviewHandlerInfo
			Dim handlerMapping As Dictionary(Of String, PreviewHandlerInfo) = New Dictionary(Of String, PreviewHandlerInfo)(handlers.Count)
			For Each handler As PreviewHandlerInfo In handlers
				handlerMapping.Add(handler.ID, handler)
			Next handler

			' Get all classes/extensions from registry
			Dim extensions As String() = Registry.ClassesRoot.GetSubKeyNames()

			' Find out what each extension is registered to be previewed with
			Dim extensionInfos As List(Of ExtensionInfo) = New List(Of ExtensionInfo)(extensions.Length)
			For Each extension As String In extensions
				If extension.StartsWith(".") Then
					Dim info As ExtensionInfo = New ExtensionInfo()
					info.Extension = extension

					Dim id As String = TryCast(Registry.GetValue(String.Format(BaseClsIDKey, extension), Nothing, Nothing), String)
					If id Is Nothing Then
						id = TryCast(Registry.GetValue(String.Format(BaseClsIdKey2, extension), Nothing, Nothing), String)
					End If
					Dim mappedHandler As PreviewHandlerInfo
					If Not id Is Nothing AndAlso handlerMapping.TryGetValue(id, mappedHandler) Then
					info.Handler = mappedHandler
					End If

					extensionInfos.Add(info)
				End If
			Next extension

			' Return the information
			Dim data As RegistrationData = New RegistrationData()
			data.Handlers = handlers
			data.Extensions = extensionInfos
			Return data
		End Function
		'TODO: INSTANT VB TODO TASK: The return type of this anonymous method could not be determined by Instant VB:
		Private Shared Function AnonymousMethod1(ByVal first As PreviewHandlerInfo, ByVal second As PreviewHandlerInfo) As Object
			If first.Name Is Nothing Then
			Return 1
			ElseIf second.Name Is Nothing Then
			Return -1
			Else
			Return first.Name.CompareTo(second.Name)
			End If
		End Function
	End Class
	Friend Class RegistrationData
		Public Handlers As List(Of PreviewHandlerInfo)
		Public Extensions As List(Of ExtensionInfo)
	End Class

	Friend Class PreviewHandlerInfo
		Public Name As String
		Public ID As String

		Public Overrides Function ToString() As String
			If String.IsNullOrEmpty(Name) Then
			Return ID
			Else
				Return Name
			End If
		End Function
	End Class

	Friend Class ExtensionInfo
		Public Extension As String
		Public Handler As PreviewHandlerInfo
		Public Overrides Function ToString() As String
			Return Extension
		End Function
	End Class
End Namespace
